package com.forezp;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;

@SpringBootApplication
@RestController
public class MyTestGatewayFirstSightApplication {

    public static void main(String[] args) {
        SpringApplication.run(MyTestGatewayFirstSightApplication.class, args);
    }


    /**
     * 一个 RouteLocatorBuilder 的bean去创建路由
     * 除了创建路由 RouteLocatorBuilder可以让你添加各种 predicates 和 filters
     *      predicates  断言的意思，顾名思义就是根据具体的请求的规则  由具体的route去处理
     *      filters     是各种过滤器，用来对请求做各种判断和修改。
     *
     * @param builder
     * @return
     */
    @Bean
    public RouteLocator myRoutes(RouteLocatorBuilder builder) {

        String httpUri = "http://httpbin.org:80";


        /**
        1. 创建的route可以让请求 “/get” 请求都 <b>转发</b>到 “http://httpbin.org/get”
        在请求 之前 ：
        2. filter会将请求添加一个header : key=hello  ； value=world。
         */
        return builder.routes()

                .route(p -> p
                        .path("/get")
                        .filters(f -> f.addRequestHeader("Hello", "World"))
                        .uri(httpUri))

                /**
                 在spring cloud gateway中可以  <b>以filter的形式使用</b> 使用 Hystrix
                 Hystrix是 spring cloud中一个服务熔断降级的组件

                 该 router 使用host去断言请求是否进入该路由  <b>当请求头部的host有“*.hystrix.com”</b>，都会进入该router
                 该 router 中有一个hystrix的filter,
                            该filter 可以配置名称、和指向性fallback的逻辑的地址，比如本案例中重定向到了“/fallback”。
                 */
                .route(p -> p
                        .host("*.hystrix.com")
                        .filters(
                                f -> f.hystrix(config -> config.setName("mycmd").setFallbackUri("forward:/fallback"))
                        )
                        .uri(httpUri)
                )
                .build();
    }


    @RequestMapping("/fallback")
    public Mono<String> fallback() {
        return Mono.just("fallback");
    }


}
